/* 
 * File:   ValueParser.cpp
 * Author: RedEyedKiller
 * 
 * Created on 16 Οκτώβριος 2011, 5:52 μμ
 */

#include "ValueParser.h"
#include "tinyxml.h"
#include "../Logger.h"
#include "../Globals.h"
#include "../ValueRepository.h"
#include "../ServiceLocator.h"

namespace FileParser
{

bool ValueParser::ParseIncludeList(TiXML::TiXmlElement* root)
{
    ValueRepository* repository = ServiceLocator<ValueRepository>::GetService( );
    TiXML::TiXmlElement* element = root->FirstChildElement( "Include" );
    while( element )
    {
        std::string filename = element->Attribute( "file" );
        unsigned int pos = filename.find_last_of( "." );

        std::string file;
        std::string fileExt;

        if( pos == filename.npos )
        {
            file = filename;
            fileExt = "";
        }
        else
        {
            file = filename.substr( 0, pos );
            fileExt = filename.substr( pos, filename.size( ) );
        }
        if( !repository->FileLoaded( file ) )
        {
            ParseFile( file, fileExt );
        }

        element = Next( element, "Include" );
    }
    return true;
}

bool ValueParser::ParseFile(const std::string& file, const std::string& fileExt)
{
    TiXML::TiXmlDocument xFile( ( Globals::GetInstance( )->GetPath( "Values" ) + file + fileExt ).c_str( ) );

    if( !xFile.LoadFile( ) )
    {
        LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_ERROR ) << "Error parsing " << ( Globals::GetInstance( )->GetPath("Values" ) +
                file + fileExt ) << " file not loaded. :" << xFile.ErrorDesc( );
        return false;
    }

    std::string filename = file + fileExt;

    TiXML::TiXmlElement* xRoot = xFile.FirstChildElement( "Values" );

    TiXML::TiXmlElement* element = xRoot->FirstChildElement( );

    ValueRepository* repository = ServiceLocator<ValueRepository>::GetService( );

    while( element )
    {
        std::string type = element->Value( );

        if( type == "int" )
        {
            int value = Parse<int>( element->Attribute( "value" ) );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<int>( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else if( type == "Vector2F" )
        {
            Math::Vector2F value = Parse<Math::Vector2F > ( element->Attribute( "value" ) );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<Math::Vector2F > ( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else if( type == "Color" )
        {
            gl::Color value = Parse<gl::Color > ( element->Attribute( "value" ) );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<gl::Color > ( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else if( type == "float" )
        {
            double value = Parse<float>( element->Attribute( "value" ) );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<float>( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else if( type == "bool" )
        {
            bool value = Parse<bool>( element->Attribute( "value" ) );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<bool>( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else if( type == "string" || type == "String" )
        {
            std::string value = element->Attribute( "value" );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<std::string > ( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else if( type == "Rect" )
        {
            const char* data = element->Attribute( "value" );
            Math::Rect value = Parse<Math::Rect > ( data );
            std::string name = element->Attribute( "name" );
            if( !repository->RegisterValue<Math::Rect > ( file, name, value ) )
            {
                LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Variable " << type << " " << name << " found in " << filename << " already defined.";
            }
        }
        else
        {
            LOG( Logger::CHANNEL_LOADING, LogFileStream::LEVEL_WARNING ) << "Unknown type " << type << " found in " << filename << ".";
        }

        {//clear up
            TiXML::TiXmlElement* tmp = element->NextSiblingElement( );
            element->Clear( );
            element = tmp;
        }

    }
    xRoot->Clear( );
    xFile.Clear( );
    return true;
}

}